package org.zn.plus.mybatis.sql.builder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.zn.plus.mybatis.sql.builder.model.Fragment;
import org.zn.plus.mybatis.sql.builder.model.JoinTable;
import org.zn.plus.mybatis.sql.builder.model.QueryOrder;
import org.zn.plus.mybatis.sql.builder.model.QueryStatement;
import org.zn.plus.mybatis.sql.builder.model.QueryTable;
import org.zn.plus.mybatis.sql.builder.model.SelectColumn;
import org.zn.plus.mybatis.sql.builder.model.Statement;
import org.zn.plus.mybatis.sql.builder.model.WhereColumn;

public class QueryBuilder implements StatementBuilder{
	
	
	private QueryStatement query;
	
	
	public QueryBuilder() {
		
		query=new QueryStatement();
		query.setParameters(new HashMap<>()); 

	}

	@Override
	public Statement buildStatement() {
		// TODO Auto-generated method stub
		
		query.setParameters(getParameters());
		
		return query;
	}

	@Override
	public Map<String, Map<String, Object>> getParameters() {
		// TODO Auto-generated method stub
		
		if(query.getParameters().isEmpty()) {
		
			doParameters(query.getMainTable());
			
		}
		
		return query.getParameters();
		
	}
	
	
	
	

	@Override
	public void setParameters(Map<String, Map<String, Object>> parameterMap) {
		query.setParameters(parameterMap);
	}
	
	
	@Override
	public void addFragment(Fragment fment, Fragment parent) {
		// TODO Auto-generated method stub
		
		fment=fment.self();
		if(parent!=null)parent=parent.self();
		
		QueryTable ptable= 	(QueryTable) parent;
		
		switch (fment.fragmentName()) {
	
		case "QueryTable":
			
			addTable((QueryTable) fment); 	break;

		case "JoinTable":
			
			addJoinTable(ptable, (JoinTable) fment);break;
			
		case "SelectColumn":

			addSelect(ptable, (SelectColumn) fment);
			
			break;
		case "WhereColumn":

			addWhere(ptable, (WhereColumn) fment);
			
			break;

		default:
			break;
		}
		
		
	}
	


	@Override
	public void addFragment(Fragment fment) {
		// TODO Auto-generated method stub
		
		addFragment(fment.self(), query.getMainTable() );

	}
	
	
	/**
	 * 默认第一次 调用为 mainTable  之后都是 join
	 * @param table
	 */
	public void addTable(QueryTable table){
		
		if(query.getMainTable()==null) 
		{
			query.setMainTable(table);
		}
		else {
			
			
			if(table instanceof JoinTable) addJoinTable((JoinTable) table);
			
			else addJoinTable(new JoinTable(table));
			
			
		}
		
		
	}
	
	
	private void doParameters(QueryTable table) {
		
		Map<String, Object> tParams=new HashMap<>();
		
		query.getParameters().put(table.getAlias(), tParams);
		
		for (WhereColumn wc : table.getWhereColumns()) {
			
			tParams.put(wc.getAlias(), wc.getParamter());
			
		}
		
		if(table instanceof JoinTable ) {
			
			for (WhereColumn oc : ((JoinTable) table).getOnList()) {
				
				if(oc.getParamter()!=null)
				tParams.put(oc.getAlias(), oc.getParamter());
				
			}
			
		}
		
		for (QueryTable intable : table.getJoinTables()) {
			
			doParameters(intable);
			
		}
		
	
		
	}
	
	
	/**
	 * @param table
	 * @param main 是否为主表  false 为 join table
	 */
	public void addJoinTable(JoinTable table){
		
		addJoinTable(null,table);
		
	}
	
	public void addJoinTable(QueryTable mtable,JoinTable jtable){
		
		if(mtable==null) {
			mtable=query.getMainTable();
		}
		
		mtable.addJoinTables(jtable);
		
		// query.addJoinTable(jtable);
		
	}
	
	
	public void addSelect(QueryTable table,SelectColumn col){
			
		if(table.getSelectColumns()==null) table.setSelectColumns(new ArrayList<>());
			
		table.getSelectColumns().add(col);
		
	}
	
	public void addWhere(QueryTable table,WhereColumn col){
		
		if(table.getWhereColumns()==null) table.setWhereColumns(new ArrayList<>());
		
		table.getWhereColumns().add(col);
		
	}
	
	public void addOrder(QueryTable table,QueryOrder order){
		
		if(table.getOrders()==null) table.setOrders(new ArrayList<>());
		
		table.getOrders().add(order);
		
	}
	
	public void addgroupBy(QueryTable table,String groupColunm){
		
		if(table.getGroupBys()==null) table.setGroupBys(new ArrayList<>());
		
		table.getGroupBys().add(groupColunm);
		
	}



	
}
